'''
Created on Jan 11, 2013

@author: mmoran
'''
import os
import webapp2
import jinja2
from webapp2_extras import auth
from webapp2_extras import sessions
from webapp2_extras.auth import InvalidAuthIdError
from webapp2_extras.auth import InvalidPasswordError

from models import AUser

jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))


class BaseHandler(webapp2.RequestHandler):
    """
         BaseHandler for all requests

         Holds the auth and session properties so they are reachable for all requests
     """

    def dispatch(self):
        """
              Save the sessions for preservation across requests
          """
        try:
            response = super(BaseHandler, self).dispatch()
            self.response.write(response)
        finally:
            self.session_store.save_sessions(self.response)

    @webapp2.cached_property
    def auth(self):
        return auth.get_auth()

    @webapp2.cached_property
    def session_store(self):
        return sessions.get_store(request=self.request)

    @webapp2.cached_property
    def auth_config(self):
        """
              Dict to hold urls for login/logout
          """
        return {
            'login_url': self.uri_for('index'),
            'logout_url': self.uri_for('logout')
        }


class IndexHandler(BaseHandler):

    def get(self):
        template = jinja_env.get_template('index.htm')
        self.response.out.write(template.render())


class LoginHandler(BaseHandler):

    def post(self):
        """
              username: Get the username from POST dict
              password: Get the password from POST dict
          """
        username = self.request.POST.get('email')
        password = self.request.POST.get('password')
        # Try to login user with password
        # Raises InvalidAuthIdError if user is not found
        # Raises InvalidPasswordError if provided password doesn't match with specified user
        try:
            user = AUser.all().filter('username =', username).filter('password =', password).get()
            if user:
                self.redirect('/home/%s/' % user.username, permanent=True)
            else:
                self.redirect('/', permanent=True)
        except (InvalidAuthIdError, InvalidPasswordError), e:
            # Returns error message to self.response.write in the BaseHandler.dispatcher
            # Currently no message is attached to the exceptions
            # return e
            self.redirect('/', permanent=True)


class RegisterUserHandler(BaseHandler):
    def get(self):
        template = jinja_env.get_template('register.htm')
        self.response.out.write(template.render())


    def post(self):
        """
              username: Get the username from POST dict
              password: Get the password from POST dict
          """
        username = self.request.POST.get('username')
        password = self.request.POST.get('password')
        first_name = self.request.POST.get('first_name')
        last_name = self.request.POST.get('last_name')
        email = self.request.POST.get('email')
        # Passing password_raw=password so password will be hashed
        # Returns a tuple, where first value is BOOL. If True ok, If False no new user is created

        nuser = AUser(username=username, password=password, first_name=first_name, last_name=last_name, email=email)
        nuser.put()

        # User is created, let's try redirecting to login page
        try:
            #self.redirect(self.auth_config['login_url'], abort=True)
            self.redirect('/home/%s/'%username,True)
        except (AttributeError, KeyError), e:
            self.abort(403)


class LogoutHandler(BaseHandler):
    """
         Destroy user session and redirect to login
     """
    def get(self):
        # User is logged out, let's try redirecting to login page
        try:
            self.redirect('/',permanent=True)
        except (AttributeError, KeyError), e:
            return "User is logged out"


class HomeHandler(BaseHandler):
    """
         Only accessible to users that are logged in
    """
    def get(self, username):
        template = jinja_env.get_template('home.htm')
        q = AUser.all()
        q.filter("username =", username)
        user = q.get()
        self.response.out.write(template.render(usuario=user))


webapp2_config = {}
webapp2_config['webapp2_extras.sessions'] = {
    'secret_key': 'Set_this_to_something_random_and_unguessable',
}

app = webapp2.WSGIApplication([
    webapp2.Route(r'/login/', handler=LoginHandler, name='login'),
    webapp2.Route(r'/logout/', handler=LogoutHandler, name='logout'),
    webapp2.Route(r'/home/<username>/', handler=HomeHandler, name='home'),
    webapp2.Route(r'/register/', handler=RegisterUserHandler, name='create-user'),
    webapp2.Route(r'/', handler=IndexHandler, name='index')
], debug=True, config=webapp2_config)